import cherrypy
import sqlite3
import time
import re

# central base class that other pages inherit
class Template:
	# header includes the logo and login/register form
	def header(self, title=None):
		if title:
			title = "%s - %s" % (title,self.getForumName())
		else:
			title = "%s" % self.getForumName()
		out = '''
			<html>
			<head>
			<title>%s</title>
		''' % title
		out += '''
            <link rel="stylesheet" type="text/css" href="/style.css" />
			</head>
			<body>
			<table width='100%' height='100px'>
				<tr id="header" valign='top'>
					<td id="logo">
						<a href="/"><h1>''' + self.getForumName() + '''</h1></a>''' + self.getForumDescription() + '''
					</td>
					<td id="logo">'''
		if not (self.getForumLogo() == "" or self.getForumLogo() == None):
			out += '''<img src="''' + self.getForumLogo() + '''" alt="No Logo"></img>'''
		out+='''</td>
					<td id="login" align="right">
		'''
		# if the user is logged in
		if self.getLoginID() != None:
			# display their username and a logout button
			out += '''Welcome, <a href="/User/%d">%s</a><br><br />
				<form method='post' action="/logout">
					<input type="submit" value="Logout"></input>
				</form>
			''' % (self.getLoginID(), self.getLoginUsername())
		else:
			# display the login/register form
			out += '''
				<form method=post action="/login">
					Username: <input name="user" type="text"></input>
					<br>
					Password: <input name="passwd" type="password"></input>
					<br>
					<input type="submit" value="Login"></input>
					<input type="submit" name="reg" value="Register"></input>
				</form>
			'''
		out += '''
					</td>
			</tr>
            </table>
		'''
		return out

	# The useful links section has the user list, PMs, and admin functions
	# links depending onthe currently logged in user's permissions
	def links(self):
		out = '''
            <table width='100%'>
			<tr valign='top'>
				<td id="links">
		'''
		
		out += '''Useful links: '''
		out += '''<a href="/User">User List</a>'''
		# display private message link if they're logged in
		if self.getLoginID() != None:
			out += ''' | <a href="/PrivateMessage">Private Messages</a>'''
		
		# if the user is logged in as an admin
		if self.getLoginPermission() == 0:
			# link to admin functions
			out += ''' | Administrator functions: <a href="/Structure">Modify forum structure</a>'''
			
		out += '''
				</td>
				<td width=30% align="right">
					<form method=get action="/search">
						<input name="q" type="text"></input><input type="submit" value="Search"></input>
					</form>
				</td>
			</tr>
            </table>
		'''
		return out

	# breadcrumbs section
	#
	# breadcrumbs are the directory-like path to where the user is looking.
	# There are multiple arguments to this function.  Only set one.  They are
	# self-explanatory, just set the ID for the view you're in and you're set.
	def breadcrumbs(self, ThreadID = None, SubforumID = None):
		cursor = cherrypy.thread_data.db.cursor()
		breadcrumb = ""

		# Thread is set, so the thread is at the end of the breadcrumb
		if ThreadID != None:
			# Get the thread's name and the subforum it's in
			cursor.execute('''
				SELECT Post.Title, Thread.SubforumID
				FROM
					Post, Thread,
					(SELECT ThreadID, MIN(Post.ID) AS MinPostID
					 FROM Post
					 GROUP BY ThreadID) Time
				WHERE
					Time.ThreadID = %s AND
					Thread.ID = Time.ThreadID AND
					Time.MinPostID = Post.ID
				''' % ThreadID)
			thread = cursor.fetchone()		
			thread_name = thread[0]
		
			if self.Thread_Closed(ThreadID):
				thread_name += " - CLOSED"

			# Put the thread at the end of the breadcrumb
			breadcrumb = " > <a href='/Thread/%s'>%s</a> %s" % (ThreadID, thread_name, breadcrumb)

			# Set the SubforumID to generate the rest of the path in the next loop
			SubforumID = thread[1]

		# Subforum ID is set, so generate the path up to the root
		while SubforumID != "NULL" and SubforumID != None:
			# Get the Name of this subforum and the parent's ID
			cursor.execute("SELECT Name, ParentSubforumID FROM Subforum WHERE ID IS ?", (SubforumID,))
			row = cursor.fetchone()

			# Add this subforum to the breadcrumb
			breadcrumb = " > <a href='/Subforum/%s'>%s</a> %s" % (SubforumID, row[0], breadcrumb)
			SubforumID = row[1]

		# Print the forum root in the breadcrumb
		breadcrumb = "> <a href='/Subforum'>%s</a> %s<br />" % (self.getForumName(), breadcrumb)

		return breadcrumb

	# This function expands generators.  This is needed if a function is
	# yielding a value from a function that yields a value.  Sometimes.  Yields
	# behave wieredly.
	def generator_expand(self, generator):
		out = ""
		for item in generator:
			out = "%s%s" % (out, item)
		return out

	# display an error page with a custom message
	def error(self, msg = 'Unknown Error', severe = False):
		out = self.header('Error')
		out += self.links()
		out += self.breadcrumbs()
		if severe:
			# red text is severe!
			out += '<font color="red">'
		out += '<h2>%s</h2>' % msg
		if severe:
			out += '</font>'
		out += self.footer()
		return out

	# static footer
	def footer(self):
		out = "<p align='center'>%s</div>"%self.getForumLegal()
		return out
		
	# Returns name/ title of forum
	def getForumName(self):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute("SELECT Name from Forum")
		name = cursor.fetchone()
		print "name: %s" % name
		if name != None:
			return name[0]
		else:
			return "Default Forum"
			
	# Return description of forum
	def getForumDescription(self):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute("SELECT Description from Forum")
		name = cursor.fetchone()
		if name != None:
			return name[0]
		else:
			return "Default Forum Info"
	
	# Return the legal info for the footer
	def getForumLegal(self):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute("SELECT LegalInfo from Forum")
		name = cursor.fetchone()
		if name != None:
			return name[0]
		else:
			return "Default Forum Info"
	
	# Return the path to the forum logo
	def getForumLogo(self):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute("SELECT Logo from Forum")
		name = cursor.fetchone()
		if name != None:
			return name[0]
		else:
			return ""
		
	# Returns the currently logged in user or None
	def getLoginID(self):
		return cherrypy.session.get('ID', None)

	# Returns the currently logged in user's name or None
	def getLoginUsername(self):
		return cherrypy.session.get('Username', None)

	# Returns user info
	def getUserInfo(self, id):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute("SELECT * FROM User WHERE ID IS ?", (id,))
		return cursor.fetchall()
	# Returns username of particular userid
	def getUsername(self, id):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute("SELECT Username FROM User WHERE ID IS ?", (id,))
		uname=cursor.fetchone()
		if uname != None:
			return uname[0]
		else:
			return None
	
	# Returns the currently logged in permission (3 if guest)
	def getLoginPermission(self):
		return cherrypy.session.get('Permission', 3)

	# This returns the name of the current subforum given its id
	def get_subforum_name(self, id):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute("SELECT Name FROM Subforum WHERE ID IS ?", (id,))

		subforum = cursor.fetchone()
		if subforum != None:
			return subforum[0]
		else:
			return None
	
	# return a list of (id, name) tuples of moderators for a given a subforum id
	def getModeratorsOf(self, SubforumID = "NULL"):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute('''
			SELECT
				User.ID, User.Username
			FROM
				User, Moderator
			WHERE
				User.Permission = 1 AND
				User.ID = Moderator.UserID AND
				Moderator.SubforumID IS ?
		''', (SubforumID,))
		return cursor.fetchall()
	
	# does the user have moderator permissions on the given thread?
	def hasPermission(self, ThreadID):
		p = self.getLoginPermission()
		if p == 3:
			# they are a guest, of course not
			return False
		if p == 0:
			# they are an admin, of course they do
			return True
		# otherwise, they're a moderator
		cursor = cherrypy.thread_data.db.cursor()
		# check if this user id is a mod of this subforum
		cursor.execute('''
			SELECT
				Moderator.UserID
			FROM
				Thread, Moderator
			WHERE
				Thread.ID IS ? AND
				Thread.SubforumID = Moderator.SubforumID
		''', (ThreadID,))
		uids = cursor.fetchall()
		if len(uids) > 0:
			id = self.getLoginID()
			for uid in uids:
				if id == uid[0]:
					return True
			return False
		else:
			return False
	
	# return the date a ban will be lifted, or None
	# unlift the ban if it has expired
	def banCheck(self, uid):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute('''SELECT BanTimestamp FROM User WHERE ID IS ?''', (uid,))
		ts = cursor.fetchone()
		if ts == None:
			return None
		ts = ts[0]
		if ts == 0:
			# permaban
			return "never"
		if time.time() > ts:
			# ban expired, lift it
			cursor.execute('''UPDATE User SET BanTimestamp = NULL WHERE ID IS ?''', (uid,))
			cherrypy.thread_data.db.commit()
			return None
		print type(ts)
		return time.ctime(ts)

	# get the ID of a thread containing a given post ID
	def getThreadID(self, postID):
		cursor = cherrypy.thread_data.db.cursor()
		cursor.execute('''
			SELECT
				ThreadID
			FROM
				Post
			WHERE
				ID = ?
		''', (postID,))
		threadID = cursor.fetchone()
		if threadID:
			return threadID[0]
		else:
			return None

	# This returns the name of the current thread given its id
	def get_thread_name(self, id):
		cursor = cherrypy.thread_data.db.cursor()

		cursor.execute('''
			SELECT Post.Title
			FROM
				Post, Thread,
				(SELECT ThreadID, MIN(Post.ID) AS MinPostID
				 FROM Post
				 GROUP BY ThreadID) Time
			WHERE
				Time.ThreadID = ? AND
				Thread.ID = Time.ThreadID AND
				Time.MinPostID = Post.ID
			''', (id,))
		thread = cursor.fetchone()

		if thread != None:
			return thread[0]
		else:
			return None

	# This generates a simple HTML document that will redirect to a given URL.
	# Note that this does not actually redirect; callers of this funciton will
	# have to manually return / yield this
	def redirect(self, path):
		return "<html><head><meta HTTP-EQUIV='REFRESH' content=\"0; url=%s\"></head></html>" % path	
	
	def Thread_Closed(self, threadid):
		cursor = cherrypy.thread_data.db.cursor() 	
		cursor.execute("SELECT Thread.Closed FROM Thread WHERE Thread.ID = ?", (threadid,))
		Closed = cursor.fetchone()[0]
		
		return Closed == 1		
	
	def strip_html_bbcode(self, string):
		p = re.compile("<.*?>")
		q = re.compile("\[.*?\]")
		return p.sub("", q.sub("", string))
